package org.finesys.common.excel.converter;

import cn.idev.excel.converters.Converter;
import cn.idev.excel.enums.CellDataTypeEnum;
import cn.idev.excel.metadata.GlobalConfiguration;
import cn.idev.excel.metadata.data.ReadCellData;
import cn.idev.excel.metadata.data.WriteCellData;
import cn.idev.excel.metadata.property.ExcelContentProperty;
import cn.idev.excel.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.finesys.common.excel.annotaion.DictTypeProperty;
import org.finesys.common.excel.enums.DictEnum;
import org.finesys.common.excel.handler.DictDataProvider;
import org.finesys.common.excel.util.SpringContextHolder;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Slf4j
public enum DictTypeConverter implements Converter<String> {


    /**
     * 实例
     */
    INSTANCE;
    public static final Map<String, DictEnum[]> cache = new HashMap<>();

    @Override
    public Class<?> supportJavaTypeKey() {
        return String.class;
    }

    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        return CellDataTypeEnum.STRING;
    }

    /**
     * 转换为 Java 数据
     *
     * @param cellData            单元格数据
     * @param contentProperty     content 属性
     * @param globalConfiguration 全局配置
     * @return {@link String }
     * @throws Exception 异常
     */
    @Override
    public String convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
        if (contentProperty == null) {
            return cellData.getStringValue();
        }
        Field field = contentProperty.getField();
        DictTypeProperty dictTypePropertyAnnotation = field.getDeclaredAnnotation(DictTypeProperty.class);
        if (Objects.isNull(dictTypePropertyAnnotation)) {
            return cellData.getStringValue();
        }
        if (dictTypePropertyAnnotation.enums().length != 0) {
            DictEnum[] dictEnum = dictTypePropertyAnnotation.enums()[0].getEnumConstants();
            return DictEnum.getValueByLabel(dictEnum, cellData.getStringValue());
        }
        DictEnum[] dictEnums = cache.get(dictTypePropertyAnnotation.value());
        if (dictEnums != null) {
            return DictEnum.getValueByLabel(dictEnums, cellData.getStringValue());
        }
        Map<String, DictDataProvider> beansOfType = SpringContextHolder.getBeansOfType(DictDataProvider.class);
        if (MapUtils.isEmpty(beansOfType)) {
            if (log.isErrorEnabled()) {
                log.error("请实现DictDataProvider接口，提供数据字典数据！");
            }
            return cellData.getStringValue();
        }
        DictDataProvider dictDataProvider = SpringContextHolder.getBean(DictDataProvider.class);
        DictEnum[] enums = dictDataProvider.getDict(dictTypePropertyAnnotation.value());
        if (enums == null) {
            if (log.isDebugEnabled()) {
                log.debug("字典数据为空:{}，自动转换失败！", dictTypePropertyAnnotation.value());
            }

            return cellData.getStringValue();
        }
        cache.put(dictTypePropertyAnnotation.value(), enums);
        return DictEnum.getValueByLabel(enums, cellData.getStringValue());
    }

    @Override
    public WriteCellData<?> convertToExcelData(String value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
        Field field = contentProperty.getField();
        DictTypeProperty dictTypePropertyAnnotation = field.getDeclaredAnnotation(DictTypeProperty.class);
        if (Objects.isNull(dictTypePropertyAnnotation)) {
            return new WriteCellData<>(value);
        }
        if (dictTypePropertyAnnotation.enums().length != 0) {
            DictEnum[] dictEnum = dictTypePropertyAnnotation.enums()[0].getEnumConstants();
            return new WriteCellData<>(DictEnum.getLabelByValue(dictEnum, value));
        }
        DictEnum[] dictEnums = cache.get(dictTypePropertyAnnotation.value());
        if (dictEnums != null) {
            String label = DictEnum.getLabelByValue(dictEnums, value);
            if (StringUtils.isEmpty(label)) {
                return new WriteCellData<>(DictEnum.getLabelByValue(dictEnums, value));
            }
        }


        Map<String, DictDataProvider> beansOfType = SpringContextHolder.getBeansOfType(DictDataProvider.class);
        if (MapUtils.isEmpty(beansOfType)) {
            if (log.isErrorEnabled()) {
                log.error("请实现DictDataProvider接口，提供数据字典数据！");
            }
            return new WriteCellData<>(value);
        }
        DictDataProvider dictDataProvider = SpringContextHolder.getBean(DictDataProvider.class);
        DictEnum[] enums = dictDataProvider.getDict(dictTypePropertyAnnotation.value());
        if (enums == null) {
            if (log.isDebugEnabled()) {
                log.debug("字典数据为空:{}，自动转换失败！", dictTypePropertyAnnotation.value());
            }
            return new WriteCellData<>(value);
        }
        String labelByValue = DictEnum.getLabelByValue(enums, value);
        if (labelByValue != null) {
            cache.put(dictTypePropertyAnnotation.value(), enums);
            return new WriteCellData<>(labelByValue);
        }
        return new WriteCellData<>(value);
    }
}
